﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TekaMUD.Engine.Framework;

namespace TekaMUD.Engine.Blocks
{
	[Flags]
	public enum EnumRoomFlags
	{
		None    =		0,
		Indoors =		1,
		NoMagic =		2,
		NoRecall =		4,
		Prison =		8,
		NoViolence =	16,
		Private =		32,
	}

	public class DirectionConnectionHelper
	{
		public RoomConnection Connection { get; set; }
		public EnumDirectionType Direction { get; set; }
	}

	public class Room : GameObject
	{
		private Dictionary<EnumDirectionType, RoomConnection> _connections;
		public ObjectContainer RoomObjects { get; private set; }
		
		/// <summary>
		/// Room Number inside the sector.
		/// </summary>
		public int SectorRoomID { get; internal set; }

		public Sector Sector {get;set;}
		public string EnterMessage { get; set; }
		public string ExitMessages { get; set; }
		public EnumRoomFlags Flags { get; set; }

		public RoomConnection GetConnection(EnumDirectionType direction)
		{
			lock (SyncRoot)
			{
				RoomConnection rc;

				if (_connections.TryGetValue(direction, out rc))
					return rc;
				
				return null;	
			}
		}

		public KeyValuePair<EnumDirectionType, RoomConnection>[] GetAllConnections()
		{
			lock (SyncRoot)
			{
				return _connections.ToArray();
			}
		}




		/// <summary>
		/// Room tile in continent map.
		/// </summary>
		public Tile Tile { get; set; }
		// Connections.

		public Room(string name)
		{
			_connections = new Dictionary<EnumDirectionType, RoomConnection>();
		
			RoomObjects = new ObjectContainer(int.MaxValue);
			Name = name;
		}

		/// <summary>
		/// Adds a connection to another room and an optional reverse connection back to this room.
		/// </summary>
		public void AddConnection(Room target, EnumDirectionType direction, EnumDirectionType? reverseDirection, Door door)
		{
			_connections[direction] = new RoomConnection() { Direction = direction, Start = this, End = target, Door = door };

			if (reverseDirection.HasValue)
				 target._connections[reverseDirection.Value] = new RoomConnection() { Start = target, End = this, Door = door, Direction = reverseDirection.Value };
		}

		/// <summary>
		/// Obtains a random room exit, or null if there is none.
		/// </summary>
		public RoomConnection GetRandomConnection(bool avoidDoors)
		{
			lock (SyncRoot)
			{
				if (avoidDoors)
				{
					List<RoomConnection> list = new List<RoomConnection>();

					foreach (KeyValuePair<EnumDirectionType, RoomConnection> kvp in _connections)
					{
						if (kvp.Value.Door == null || kvp.Value.Door.Opened)
							list.Add(kvp.Value);
					}

					if (list.Count == 0)
						return null;

					return list[Randomizer.GetInteger(0, list.Count - 1)];
				}
				else
				{
					if (_connections.Count == 0)
						return null;

					int rnd = Randomizer.GetInteger(0, _connections.Count -1);
					return _connections.ToArray()[rnd].Value;
				}
			}
		}

		public override string ToString()
		{
			return UID.ToString("n") + " - " + Name;
		}
	}
}
